package com.springboot.websocket;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint(value = "/ws/idealwidget/{userId}", configurator = CORSConfigurator.class)
public class IdealWidgetWebSocket {

    private static final Logger log = LoggerFactory.getLogger(IdealWidgetWebSocket.class);

    /**
     * concurrent包的线程安全，用来存放每个客户端对应的MyWebSocket对象。module对应链接
     */
    private static ConcurrentHashMap<String, IdealWidgetWebSocket> webSocketMap = new ConcurrentHashMap<>();
    /**
     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 用户id
     */
    private String userId;

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        try {
            WebSocketRepVO repVO = new WebSocketRepVO();
            if (webSocketMap.containsKey(this.userId)) {
                repVO.setStatus("REFUSE");
                repVO.setMsg("请等待其他用户操作完成。");
                sendMessage(JSONUtil.toJsonStr(repVO));
                log.info("用户：{}，连接失败。", this.userId);
            } else {
                webSocketMap.put(this.userId, this);
                repVO.setStatus("OPEN");
                repVO.setMsg("开始操作。");
                sendMessage(JSONUtil.toJsonStr(repVO));
                log.info("用户：{}，连接成功。", this.userId);
            }
        } catch (IOException e) {
            log.error("用户:{},网络异常!", this.userId);
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if (webSocketMap.containsKey(this.userId)) {
            webSocketMap.remove(this.userId);
            log.info(" 用户:{}，退出连接。", this.userId);
        }
    }

    /**
     * 根据用户发送自定义消息
     */
    public static void sendInfoByUserId(String userId, String message) {
        try {
            if (StrUtil.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
                log.info("用户：{}发送消息:{}", userId, message);
            }
            IdealWidgetWebSocket idealWidgetWebSocket = webSocketMap.get(userId);
            if (idealWidgetWebSocket != null) {
                idealWidgetWebSocket.sendMessage(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage(maxMessageSize = 3000000)
    public void onMessage(String message) throws Exception {
        log.info("用户:{},接收到消息报文:{}", this.userId, message);
    }

    /**
     * @param error
     */
    @OnError
    public void onError(Throwable error) {
        log.error("用户:{},错误原因:{}", this.userId, error.getMessage());
        error.printStackTrace();
    }
}
